#include "hx711.h"

GPIO_Module* Calibrate_Port;
uint16_t Calibrate_Pin = INVALID_PIN;
int32_t CalibrateWeight = -1;
void HX711_Initial(GPIO_Module* calibratePort,uint16_t calibratePin,int32_t calibrateWeight)
{
	GPIO_InitType GPIO_InitStructure;

	RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
	GPIO_InitStruct(&GPIO_InitStructure);
	GPIO_InitStructure.Pin = CZSKPin;
	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitPeripheral(CZPort, &GPIO_InitStructure);	
	GPIO_ResetBits(CZPort,	CZSKPin);
	GPIO_InitStructure.Pin = CZDIOPin;
	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT;
	GPIO_InitPeripheral(CZPort, &GPIO_InitStructure);	
	
	Calibrate_Port = calibratePort;
	Calibrate_Pin = calibratePin;	
	CalibrateWeight = calibrateWeight;
	switch ((uint32_t)Calibrate_Port)
	{
		case (uint32_t)GPIOA:
			RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
			break;
		case (uint32_t)GPIOB:
			RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
			break;
		case (uint32_t)GPIOC:
			RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE);
			break;
		case (uint32_t)GPIOF:
			RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOF, ENABLE);	
			break;
	}
	GPIO_InitStructure.Pin        = Calibrate_Pin;
	GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_INPUT;
	GPIO_InitStructure.GPIO_Pull  = GPIO_PULL_UP;
	GPIO_InitPeripheral(Calibrate_Port, &GPIO_InitStructure);
	
}

u8 Is_HX711_Ready(void)
{
	return (GPIO_ReadInputDataBit(CZPort,CZDIOPin) == Bit_RESET);
}

int32_t	HX711_Read(void)
{
	u32 count = 0;
	u8 idx;
		
	GPIO_ResetBits(CZPort,	CZSKPin);
	while(GPIO_ReadInputDataBit(CZPort,CZDIOPin) == Bit_SET);
	for (idx = 0;idx < 24; idx ++)
	{
		GPIO_SetBits(CZPort,	CZSKPin);
		delay_us(1);
		count <<= 1;
		if (GPIO_ReadInputDataBit(CZPort,CZDIOPin) == Bit_SET)
			count ++;
		GPIO_ResetBits(CZPort,	CZSKPin);
		delay_us(1);
	}
	GPIO_SetBits(CZPort,	CZSKPin);
	delay_us(1);
	GPIO_ResetBits(CZPort,	CZSKPin);
	delay_us(1);
	
	count ^= 0x800000;
	return count;
}

//float calibration_factor = -7050.0; 
//int32_t offset = 0;

float Get_Weight() 
{
  int32_t raw_data = HX711_Read();
  float weight = (raw_data - CurSetting.HXOffset) / CurSetting.HXCalibrate;
  return weight;
}

void WaitCalibrateSignal(void)
{
	while(true)
	{
		if (Calibrate_Pin != INVALID_PIN)
		{
			if (!GPIO_ReadInputDataBit(Calibrate_Port,Calibrate_Pin))
				break;
		}
	}
}

void Calibrate(int32_t * pHXOffset,float * pHXAdjust) 
{
	int32_t raw_value;
	
	if (CalibrateWeight == -1)
		return;
  *pHXOffset = HX711_Read(); 
  WaitCalibrateSignal();
  raw_value = HX711_Read();
  *pHXAdjust = (raw_value - *pHXOffset) / CalibrateWeight;
}

